package zzps.exeed.kernel.convert.impl;

import zzps.exeed.kernel.convert.Convert;
import zzps.exeed.kernel.convert.Converter;
import zzps.exeed.kernel.tool.CharPool;
import zzps.exeed.kernel.tool.StrTool;

import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.List;

public class ArrayConverter implements Converter<Object> {
    private final Class<?> targetType;
    /**
     * 目标元素类型
     */
    private final Class<?> targetComponentType;

    public ArrayConverter(Class<?> targetType) {
        this.targetType = targetType;
        targetComponentType = targetType.getComponentType();
    }

    @Override
    public Object convert(Object value) {
        return value.getClass().isArray() ? convertArrayToArray(value) : convertObjectToArray(value);
    }

    /**
     * 数组对数组转换
     *
     * @param array 被转换的数组值
     * @return 转换后的数组
     */
    private Object convertArrayToArray(Object array) {
        final Class<?> valueComponentType = array.getClass().getComponentType();
        if (valueComponentType == targetComponentType) {
            return array;
        }
        final int len = Array.getLength(array);
        final Object result = Array.newInstance(targetComponentType, len);
        for (int i = 0; i < len; i++) {
            Array.set(result, i, Convert.convert(targetComponentType,Array.get(array, i)));
        }
        return result;
    }
    /**
     * 非数组对数组转换
     *
     * @param value 被转换值
     * @return 转换后的数组
     */
    private Object convertObjectToArray(Object value) {
        if (value instanceof CharSequence) {
            if (targetComponentType == char.class || targetComponentType == Character.class) {
                return convertArrayToArray(value.toString().toCharArray());
            }
            if(targetComponentType == byte.class){
                return value.toString().getBytes();
            }
            // 单纯字符串情况下按照逗号分隔后劈开
            List<String> stringList = StrTool.split(value.toString(), ',');
            String[] split = stringList.toArray(new String[stringList.size()]);
            return convertArrayToArray(split);
        }

        Object result;
        if (value instanceof List) {
            // List转数组
            final List<?> list = (List<?>) value;
            result = Array.newInstance(targetComponentType, list.size());
            for (int i = 0; i < list.size(); i++) {
                Array.set(result, i, Convert.convert(targetComponentType,list.get(i)));
            }
        } else if (value instanceof Collection) {
            // 集合转数组
            final Collection<?> collection = (Collection<?>) value;
            result = Array.newInstance(targetComponentType, collection.size());
            int i = 0;
            for (Object element : collection) {
                Array.set(result, i, Convert.convert(targetComponentType,element));
                i++;
            }
        }  else {
            // everything else:
            result =  Array.newInstance(targetComponentType, 1);
            Object[] objects = (Object[]) result;
            objects[0] = Convert.convert(targetComponentType,value);
        }
        return result;
    }
}
